package db_meta

import (
	"strconv"

	"engine/db"
	"servers/models/define"
	"servers/models/meta"
	"servers/models/protos/google/pb/rpc_protos"

	"gitee.com/ameise84/e3utils/str_conv"
	jsoniter "github.com/json-iterator/go"
	"gorm.io/gorm"
)

func init() {
	db.RegisterTableMetaFactory(CfgAutoCtrlFactory)
	db.RegisterTableMetaFactory(CfgGameFactory)
	db.RegisterTableMetaFactory(CfgRtpFactory)
}

func CfgAutoCtrlFactory() db.TableMeta {
	return &CfgAutoCtrl{}
}

type CfgAutoCtrl struct {
	CtrlID           uint32           `json:"id" form:"id" gorm:"primarykey;column:id"` // 平台ID
	BusinessID       uint32           `json:"bid" form:"bid" gorm:"column:bid"`
	Status           bool             `json:"status" form:"status" gorm:"column:status"`
	TriggerRate      int              `json:"trigger_rate" form:"trigger_rate" gorm:"column:trigger_rate"`
	CtrlJs           string           `json:"ctrl_js" form:"ctrl_js" gorm:"column:ctrl_js"`
	FirstLoginTime   int64            `json:"first_login_time" form:"first_login_time" gorm:"column:first_login_time"` // 判断首次登录时间(秒, 0表示不判断时间)
	AvgBetScoreMin   define.GameScore `json:"avg_bet_score_min" form:"avg_bet_score_min" gorm:"column:avg_bet_score_min"`
	AvgBetScoreMax   define.GameScore `json:"avg_bet_score_max" form:"avg_bet_score_max" gorm:"column:avg_bet_score_max"`
	TotalWinScore    define.GameScore `json:"total_win_score" form:"total_win_score" gorm:"column:total_win_score"`
	TodayWinScore    define.GameScore `json:"today_win_score" form:"today_win_score" gorm:"column:today_win_score"`
	TotalRound       int64            `json:"total_round" form:"total_round" gorm:"column:total_round"`
	TodayRound       int64            `json:"today_round" form:"today_round" gorm:"column:today_round"`
	RechargeScoreMin define.GameScore `json:"recharge_score_min" form:"recharge_score_min" gorm:"column:recharge_score_min"`
	RechargeScoreMax define.GameScore `json:"recharge_score_max" form:"recharge_score_max" gorm:"column:recharge_score_max"`
	TotalCtrlTimes   int64            `json:"total_ctrl_times" form:"total_ctrl_times" gorm:"column:total_ctrl_times"`
	TodayCtrlTimes   int64            `json:"today_ctrl_times" form:"today_ctrl_times" gorm:"column:today_ctrl_times"`
}

func (v *CfgAutoCtrl) BaseTableName() string {
	return v.TableName()
}

func (v *CfgAutoCtrl) TableName() string {
	return "cfg_auto_ctrl"
}

func (v *CfgAutoCtrl) ID() string {
	return str_conv.ToString(v.CtrlID)
}

func (v *CfgAutoCtrl) MarshalBinary() (data []byte, err error) {
	return jsoniter.Marshal(v)
}

func (v *CfgAutoCtrl) UnmarshalBinary(data []byte) error {
	return jsoniter.Unmarshal(data, v)
}

func (v *CfgAutoCtrl) FromPB(meta *rpc_protos.AddAutoCtrlCast) {
	v.BusinessID = meta.Bid
	v.Status = meta.Status == 1
	v.TriggerRate = int(meta.TriggerRate)
	v.CtrlJs = meta.CtrlJson
	v.FirstLoginTime = meta.FirstLoginTime
	v.AvgBetScoreMin = meta.AvgBetScoreMin
	v.AvgBetScoreMax = meta.AvgBetScoreMax
	v.TotalWinScore = meta.TotalWinScore
	v.TodayWinScore = meta.TodayWinScore
	v.TotalRound = meta.TotalRound
	v.TodayRound = meta.TodayRound
	v.RechargeScoreMin = meta.RechargeScoreMin
	v.RechargeScoreMax = meta.RechargeScoreMax
	v.TotalCtrlTimes = meta.TotalCtrlTimes
	v.TodayCtrlTimes = meta.TodayCtrlTimes
}

func CfgGameFactory() db.TableMeta {
	return &CfgGame{}
}

type CfgGame struct {
	GameKindID uint32              `json:"id" form:"id" gorm:"primarykey;column:id"`
	Name       string              `json:"name" form:"name" gorm:"column:name"`
	RTPLevel   define.RTPIndexType `json:"rtp_level" form:"rtp_level" gorm:"column:rtp_level"`
	ExpectRTP  define.RTPValue     `json:"expect_rtp" form:"expect_rtp" gorm:"column:expect_rtp"`
	Image      string              `json:"image" form:"image" gorm:"column:image"`
	GameType   uint32              `json:"game_type" form:"game_type" gorm:"column:game_type"`
}

func (v *CfgGame) BaseTableName() string {
	return v.TableName()
}

func (v *CfgGame) TableName() string {
	return "cfg_game"
}

func (v *CfgGame) ID() string {
	return str_conv.ToString(v.GameKindID)
}

func (v *CfgGame) MarshalBinary() (data []byte, err error) {
	return jsoniter.Marshal(v)
}

func (v *CfgGame) UnmarshalBinary(data []byte) error {
	return jsoniter.Unmarshal(data, v)
}

func CfgRtpFactory() db.TableMeta {
	return &CfgRtp{}
}

type CfgRtp struct {
	TacticLevel  define.RTPIndexType  `json:"id" form:"id" gorm:"primarykey;column:id"`
	TotalRTP     meta.RtpArray        `gorm:"-"`
	TotalRTPJson string               `json:"total_rtp" form:"total_rtp" gorm:"column:total_rtp"`
	DailyRTP     meta.RtpArray        `gorm:"-"`
	DailyRTPJson string               `json:"daily_rtp" form:"daily_rtp" gorm:"column:daily_rtp"`
	RoundRTP     meta.RtpArray        `gorm:"-"`
	RoundRTPJson string               `json:"round_rtp" form:"round_rtp" gorm:"column:round_rtp"`
	Restore      meta.RtpRestoreArray `gorm:"-"`
	RestoreJson  string               `json:"restore" form:"restore" gorm:"column:restore"`
}

func (v *CfgRtp) BaseTableName() string {
	return v.TableName()
}

func (v *CfgRtp) TableName() string {
	return "cfg_rtp"
}

func (v *CfgRtp) ID() string {
	return str_conv.ToString(v.TacticLevel)
}

func (v *CfgRtp) MarshalBinary() (data []byte, err error) {
	return jsoniter.Marshal(v)
}

func (v *CfgRtp) UnmarshalBinary(data []byte) error {
	return jsoniter.Unmarshal(data, v)
}

func (v *CfgRtp) AfterFind(tx *gorm.DB) (err error) {
	var tmpT, tmpD, tmpR, tmpS [][]int64
	_ = jsoniter.UnmarshalFromString(v.TotalRTPJson, &tmpT)
	_ = jsoniter.UnmarshalFromString(v.DailyRTPJson, &tmpD)
	_ = jsoniter.UnmarshalFromString(v.RoundRTPJson, &tmpR)
	_ = jsoniter.UnmarshalFromString(v.RestoreJson, &tmpS)
	if len(tmpT) == 0 || len(tmpD) == 0 || len(tmpR) == 0 || len(tmpS) == 0 {
		return nil
	}
	v.TotalRTP.FromSlice(tmpT)
	v.DailyRTP.FromSlice(tmpD)
	v.RoundRTP.FromSlice(tmpR)
	v.Restore.FromSlice(tmpS)
	return
}

type CfgGameGroups struct {
	Id   uint                           `json:"id" form:"id" gorm:"primarykey;column:id"`
	Data string                         `json:"data" form:"data" gorm:"column:data"`
	List []*rpc_protos.GameBaseInfoMeta `gorm:"-"`
}

func (v *CfgGameGroups) BaseTableName() string {
	return "cfg_game_groups"
}

func (v *CfgGameGroups) TableName() string {
	return v.BaseTableName()
}

func (v *CfgGameGroups) ID() string {
	return str_conv.ToString(v.Id)
}

func (v *CfgGameGroups) MarshalBinary() (data []byte, err error) {
	return jsoniter.Marshal(v)
}

func (v *CfgGameGroups) UnmarshalBinary(data []byte) error {
	return jsoniter.Unmarshal(data, v)
}

func (v *CfgGameGroups) AfterFind(tx *gorm.DB) (err error) {
	var tmp [][]uint64
	_ = jsoniter.UnmarshalFromString(v.Data, &tmp)
	if len(tmp) == 0 {
		return nil
	}
	for _, vs := range tmp {
		m := rpc_protos.GameBaseInfoMeta{}
		m.GameKindID = uint32(vs[0])
		m.Sort = uint32(vs[1])
		m.Mark = vs[2]
		v.List = append(v.List, &m)
	}
	return
}

type CfgScoreType struct {
	Id       uint  `json:"id" form:"id" gorm:"primarykey;column:id"`
	Exchange int64 `json:"exchange" form:"exchange" gorm:"column:exchange"`
}

func (v *CfgScoreType) BaseTableName() string {
	return "cfg_score_type"
}

func (v *CfgScoreType) TableName() string {
	return v.BaseTableName()
}

func (v *CfgScoreType) ID() string {
	return strconv.Itoa(int(v.Id))
}

func (v *CfgScoreType) MarshalBinary() (data []byte, err error) {
	return jsoniter.Marshal(v)
}

func (v *CfgScoreType) UnmarshalBinary(data []byte) error {
	return jsoniter.Unmarshal(data, v)
}
